package com.tfswx.ruleengine.database.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.*;
import java.util.Enumeration;

/**
 * @author Ricky
 * @date 2020/12/21
 */
@Slf4j
public class NetworkUtil {
    private NetworkUtil() {
    }

    public static String getIpAddress() {
        String unknown = "unknown";

        // 鑾峰彇褰撳墠鐨凥ttpServletRequest瀵硅薄
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            log.info("不是真实请求");
            return "0.0.0.0";
        }
        HttpServletRequest request = attributes.getRequest();

        // 鑾峰彇璇锋眰涓绘満IP鍦板潃,濡傛灉閫氳繃浠ｇ悊杩涙潵锛屽垯閫忚繃闃茬伀澧欒幏鍙栫湡瀹濱P鍦板潃

        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
                if (ip.equals("127.0.0.1") || ip.equals("0:0:0:0:0:0:0:1")) {
                    //鏍规嵁缃戝崱鍙栨湰鏈洪厤缃殑IP
                    InetAddress inet;
                    try {
                        inet = InetAddress.getLocalHost();
                        ip = inet.getHostAddress();
                    } catch (UnknownHostException e) {
                    }
                }
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (String strIp : ips) {
                if (!(unknown.equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }

    public static String getHost() {
        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = allNetInterfaces.nextElement();
                if (netInterface.isVirtual() || !netInterface.isUp() || netInterface.isLoopback()) {
                    continue;
                }
                Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress inetAddress = addresses.nextElement();
                    if (inetAddress instanceof Inet4Address) {
                        return inetAddress.getHostAddress();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "127.0.0.1";
    }

    /**
     * 根据本机ip扫描局域网设备
     *
     * @param address
     */
    private static void scannerNetwork(String address) {
        try {
            // 设置IP地址网段
            String ips = getNetworkSegment(address);

            System.out.println("开始扫描 " + ips + "网段...");

            String ip;
            InetAddress addip = null;
            // 遍历IP地址
            for (int i = 1; i < 255; i++) {
                ip = ips + i;
                try {
                    addip = InetAddress.getByName(ip);
                } catch (UnknownHostException e) {
                    System.out.println("找不到主机: " + ip);
                }
                // 获取登录过的设备
                if (!ip.equals(addip.getHostName())) {
                    try {
                        // 检查设备是否在线，其中1000ms指定的是超时时间
                        // 当返回值是true时，说明host是可用的，false则不可。
                        boolean status = InetAddress.getByName(addip.getHostName()).isReachable(1);
                        System.out.println("IP地址为:" + ip + "\t\t设备名称为: " + addip.getHostName() + "\t\t是否可用: "
                                + (status ? "可用" : "不可用"));
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception uhe) {
            System.err.println("Unable to find: " + uhe.getLocalizedMessage());
        }
    }

    public static String getHost(String url) {
        URL u = null;
        try {
            u = new URL(url);
        } catch (MalformedURLException e) {
            throw new RuntimeException("url" + url + "格式不正确");
        }
        return u.getHost();
    }

    public static String getPath(String url) {
        URL u = null;
        try {
            u = new URL(url);
        } catch (MalformedURLException e) {
            throw new RuntimeException("url" + url + "格式不正确");
        }
        return u.getPath();
    }

    public static String getUrl(String url) {
        URL u = null;
        try {
            u = new URL(url);
        } catch (MalformedURLException e) {
            throw new RuntimeException("url" + url + "格式不正确");
        }
        return u.getProtocol() + "://" + u.getHost() + ":" + u.getPort() + u.getPath();
    }

    /**
     * 根据ip获取网段
     *
     * @param ip
     * @return
     */
    private static String getNetworkSegment(String ip) {
        int startIndex = ip.lastIndexOf(".");
        return ip.substring(0, startIndex + 1);
    }


    public static void main(String[] args) throws MalformedURLException, UnknownHostException {
        String host = getHost();
        System.out.println(host);
        scannerNetwork(host);
        //        Set<String> set = getHost();
        //        if (set.size() > 0) {
        //            set.forEach(ip -> {
        //                System.out.println("本机ip: " + ip);
        //            });
        //        }
    }
}
